<?php
namespace Realisation\Web\Builder;

use Doctrine\DBAL\Driver\Statement;

/**
 * Description of XmlBuilder
 *
 * @author pahhan
 */
class XmlBuilder implements BuilderInterface
{
    /**
     * Returns new XML document
     * @return \DOMDocument
     */
    private function createDocument()
    {
        return new \DOMDocument('1.0', 'utf-8');
    }

    /**
     * Adds new DOM element with $name, $value to $parent
     * @param DOMNode $parent
     * @param string $name
     * @param string $value
     * @param DOMDocument $document
     */
    private function addElement(\DOMNode $parent, $name, $value, \DOMDocument $document)
    {
        $new = $document->createElement($name, $value);
        $parent->appendChild($new);
    }

    /**
     * Returns error element
     * @param DOMDocument $document
     * @param integer $code
     * @param string $message
     * @return DOMElement
     */
    private function createErrorElement(\DOMDocument $document, $code = 0, $message = NULL)
    {
        $code = $document->createElement('code', $code);
        $message = $document->createElement('message', $message);

        $element = $document->createElement('error');

        $element->appendChild($code);
        $element->appendChild($message);

        return $element;
    }

    /**
     * Returns message DOM element from array
     * @param array $message
     * @param DOMDocument $document
     * @return DOMElement
     */
    private function createMessageElement(array $message, \DOMDocument $document)
    {
        $message_el = $document->createElement('message');
        $this->addElement($message_el, 'id', $message['id'], $document);
        $this->addElement($message_el, 'url_id', $message['url_id'], $document);
        $this->addElement($message_el, 'external_id', $message['external_id'], $document);
        $this->addElement($message_el, 'published_at', $message['published_at'], $document);
        $this->addElement($message_el, 'title', $message['title'], $document);
        $cdata = $document->createCDATASection($message['content']);
        $content = $document->createElement('content');
        $content->appendChild($cdata);
        $message_el->appendChild($content);
        $this->addElement($message_el, 'tags', $message['tags'], $document);
        return $message_el;
    }

    public function buildMessages(Statement $stmt)
    {
        $document = $this->createDocument();
        $data = $document->createElement('data');
        $document->appendChild($data);
        $data->appendChild($this->createErrorElement($document));

        $messages_el = $document->createElement('messages');

        while($message = $stmt->fetch()) {
            $messages_el->appendChild($this->createMessageElement($message, $document));
        }

        $data->appendChild($messages_el);

        return $document->saveXML();
    }

    /**
     * Returns site DOM element from array
     * @param array $site
     * @param DOMDocument $document
     * @return DOMElement
     */
    private function createSiteElement(array $site, \DOMDocument $document)
    {
        $site_el = $document->createElement('site');
        $this->addElement($site_el, 'id', $site['id'], $document);
        $this->addElement($site_el, 'title', $site['title'], $document);
        $this->addElement($site_el, 'url', $site['url'], $document);
        $this->addElement($site_el, 'description', $site['description'], $document);
        $this->addElement($site_el, 'logo', NULL, $document);
        $this->addElement($site_el, 'updated_at', $site['updated_at'], $document);
        return $site_el;
    }

    public function buildSites(Statement $stmt)
    {
        $document = $this->createDocument();
        $data = $document->createElement('data');
        $document->appendChild($data);
        $data->appendChild($this->createErrorElement($document));

        $sites_el = $document->createElement('sites');

        while ($site = $stmt->fetch()) {
            $sites_el->appendChild($this->createSiteElement($site, $document));
        }

        $data->appendChild($sites_el);

        return $document->saveXML();
    }

    /**
     * Returns site DOM element from array
     * @param array $url
     * @param DOMDocument $document
     * @return DOMElement
     */
    private function createUrlElement(array $url, \DOMDocument $document)
    {
        $url_el = $document->createElement('url');
        $this->addElement($url_el, 'id', $url['id'], $document);
        $this->addElement($url_el, 'site_id', $url['site_id'], $document);
        $this->addElement($url_el, 'title', $url['title'], $document);
        $this->addElement($url_el, 'url', $url['url'], $document);
        $this->addElement($url_el, 'description', $url['description'], $document);
        $this->addElement($url_el, 'updated_at', $url['updated_at'], $document);
        return $url_el;
    }

    public function buildUrl(Statement $stmt)
    {
        $document = $this->createDocument();
        $data = $document->createElement('data');
        $document->appendChild($data);
        $data->appendChild($this->createErrorElement($document));

        $urls_el = $document->createElement('urls');

        while ($url = $stmt->fetch()) {
            $urls_el->appendChild($this->createUrlElement($url, $document));
        }

        $data->appendChild($urls_el);

        return $document->saveXML();
    }

    public function buildMessagesCount(Statement $stmt)
    {
        $document = $this->createDocument();
        $data = $document->createElement('data');
        $document->appendChild($data);
        $data->appendChild($this->createErrorElement($document));
        $count = $stmt->fetchColumn();
        $data->appendChild($document->createElement('count', $count));
        return $document->saveXML();
    }
}
